package com.qsw.crashcollectionlib.view;

import android.app.Application;

import com.qsw.crashcollectionlib.core.CrashExceptionProcesser;
import com.qsw.crashcollectionlib.core.ExceptionTask;
import com.qsw.crashcollectionlib.utils.ExceptionLogUtils;

import java.io.File;
import java.io.FilenameFilter;

/**
 * 一些日志文件默认配置以及未捕获异常配置
 */
public abstract class CrashApplication extends Application {
    private final String FOLDER_CRASH = "crashLog";
    private final String PREFIX_LOGFILE = "default_";

    @Override
    public void onCreate() {
        super.onCreate();

        setDefaultCrashLogPath(getDefaultCrashLogPath(), getDefaultCrashLogName());

        ExceptionTask.getInstance().setOnTaskSizeDangerListener(mOnTaskSizeDangerListener);
    }

    /**
     * 结束
     */
    @Override
    public void onTerminate() {
        ExceptionTask.getInstance().shotdown();
        super.onTerminate();
    }

    /**
     * 获取默认异常日志文件路径
     *
     * @return 日志文件的绝对路径
     */
    private String getDefaultCrashLogPath() {
        return getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + File.separator + FOLDER_CRASH;
    }

    /**
     * 获取默认异常日志文件名
     *
     * @return 日志文件名
     */
    private String getDefaultCrashLogName() {
        return PREFIX_LOGFILE + getPackageName();
    }

    /**
     * 设置默认日志文件
     *
     * @param defaultCrashLogPath       默认的异常日志存储路径
     * @param defaultCrashLogNamePrefix 默认的异常日志文件名前缀
     */
    protected void setDefaultCrashLogPath(String defaultCrashLogPath, String defaultCrashLogNamePrefix) {
        setDefaultCrashLogPath(defaultCrashLogPath, defaultCrashLogNamePrefix, null);
    }

    /**
     * 设置默认日志文件
     *
     * @param defaultCrashLogPath        默认的异常日志存储路径
     * @param defaultCrashLogNamePrefix  默认的异常日志文件名前缀
     * @param defaultCrashLogNameSufffix 默认的异常日志文件名后缀，不能包含“_”
     */
    protected void setDefaultCrashLogPath(String defaultCrashLogPath, String defaultCrashLogNamePrefix, String defaultCrashLogNameSufffix) {
        CrashExceptionProcesser.getInstance().initLogFileSetting(defaultCrashLogPath, defaultCrashLogNamePrefix, defaultCrashLogNameSufffix);
    }

    /**
     * 开启默认日志文件按日期新建
     */
    protected void enableDefaultCrashLogByDate() {
        CrashExceptionProcesser.setDefaultLogNameByDate(true);
    }

    /**
     * 关闭默认日志文件按日期新建
     */
    protected void disableDefaultCrashLogByDate() {
        CrashExceptionProcesser.setDefaultLogNameByDate(false);
    }

    /**
     * 设置默认日志文件最大长度
     *
     * @param maxLength 文件最大长度，超过该长度则创建新日志文件，单位b
     */
    protected void setDefaultCrashLogMaxLength(int maxLength) {
        CrashExceptionProcesser.setDefaultLogFileMaxLength(maxLength);
    }

    /**
     * 设置日志文件命名检测间隔，不建议小于{@link CrashExceptionProcesser#getDefaultLogFileNameCheckInterval()}
     *
     * @param checkInterval 日志文件命名检测间隔，不建议小于{@link CrashExceptionProcesser#getDefaultLogFileNameCheckInterval()}，单位毫秒
     */
    protected void setDefaultCrashLogNameCheckInterval(long checkInterval) {
        CrashExceptionProcesser.setDefaultLogFileNameCheckInterval(checkInterval);
    }

    /**
     * 清除超过指定日期前的日志文件
     *
     * @param time 时间戳，该时间戳前创建的文件将被删除
     */
    protected void clearCrashLogFileOutDate(long time) {
        ExceptionLogUtils.clearCrashLogFileOutDate(time);
    }

    /**
     * 若默认目录中的日志总大小超过指定大小，则以时间最早的开始删除，直至大小下降到指定以下，以最后一次修改时间为准
     *
     * @param maxSize  最大大小，单位byte
     * @param needSize 若超过maxSize则降到needSize以下，单位byte，必须小于maxSize
     */
    public static void clearCrashLogFileIfOutFullSize(long maxSize, long needSize) {
        ExceptionLogUtils.clearCrashLogFileIfOutFullSize(maxSize, needSize);
    }

    /**
     * 当存储任务过多时的回调
     *
     * @param danger true：危险；false：安全
     * @param size   当前数量
     */
    public abstract void onTaskSizeDanger(boolean danger, int size);

    /**
     * 当存储任务过多时的回调
     */
    private final ExceptionTask.OnTaskSizeDangerListener mOnTaskSizeDangerListener = new ExceptionTask.OnTaskSizeDangerListener() {
        @Override
        public void onTaskSizeDanger(boolean danger, int size) {
            CrashApplication.this.onTaskSizeDanger(danger, size);
        }
    };
}
